<?php
/*
 * Created on 2012-5-8
 * @iChying
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */

 class UnicodeCompress {
 	public static $encode_index_table;
 	private $compress_table;

 	public function __construct() {
 		$this->initialize();
 	}

 	private function initialize() {
 		$this->generateEncodeTable();
 		$this->generateCompressTable();
 	}

 	private function generateEncodeTable() {
 		self::$encode_index_table = array();

		// A-Z
 		for ($i = 0; $i < 26; ++$i) {
 			self::$encode_index_table[$i] = chr(ord('A') + $i);
 		}

		// a-z
 		for ($i = 0; $i < 26; ++$i) {
 			self::$encode_index_table[] = chr(ord('a') + $i);
 		}

		// 0-9
 		for ($i = 0; $i < 10; ++$i) {
 			self::$encode_index_table[] = chr(ord('0') + $i);
 		}

		// + /
 		self::$encode_index_table[] = '+';
 		self::$encode_index_table[] = '/';
 	}

 	private function generateCompressTable() {
		function gen_enarray($value) {
			$bit_val0 = $value;
			$bit_val1 = $value << 2;
			$bit_val2 = ($value & 0x0c) >> 2;
			$bit_val3 = ($value & 0x03) << 4;

			return array($bit_val0, $bit_val1, $bit_val2, $bit_val3);
		}

		$this->compress_table = array();

		// 0-9 a-f
		for ($i = 0; $i < 16; ++$i) {
			$this->compress_table[$i] = gen_enarray($i);
		}
 	}

	public function compressUnicode($codePointStr) {
		$compressResult = '';
		$codePointLength = strlen($codePointStr);

		for ($i = 0; $i < $codePointLength;) {
			$ch1 = hexdec($codePointStr{$i++});
			$ch2 = hexdec($codePointStr{$i++});
			$ch3 = hexdec($codePointStr{$i++});
			$ch4 = hexdec($codePointStr{$i++});

			// echo $ch1, ' ', $ch2, ' ', $ch3, ' ', $ch4, '<br />';

			$encodeIndex1 = ($this->compress_table[$ch1][1]) | ($this->compress_table[$ch2][2]);
			$encodeIndex2 = ($this->compress_table[$ch2][3]) | ($this->compress_table[$ch3][0]);
			$encodeIndex3 = $this->compress_table[$ch4][1];

			if (($ch2 & 3) == 3 && $ch3 >= 14) {
				$encodeIndex2 = ($encodeIndex2 & 0x37); // 11011x
				$encodeIndex3 = ($encodeIndex3 | 0x1); // xxxx01
			}

			// echo $encodeIndex1, ' ', $encodeIndex2, ' ',$encodeIndex3, "<br />";
			$compressResult .= self::$encode_index_table[$encodeIndex1];
			$compressResult .= self::$encode_index_table[$encodeIndex2];
			$compressResult .= self::$encode_index_table[$encodeIndex3];

		}

		return $compressResult;
	}
 }

?>